package com.keithpower.freshdox;

import java.util.Hashtable;

/**
 * This class implements some basic functionality common to most TestExecuters
 * 
 * In particular, it examines a test's dependencies, checks to see it the
 * referred to tests have executed, and if they have, sees whether they passed
 * or not. If one of them failed, the test is not executed.
 * 
 * More complex behaviour may be required in some cases. For instance, if a test
 * F depends on other tests A, B and C, but tests D, E and F have already been
 * carried out, then the outcome of F may be different then it would've been if
 * only A, B and C were executed. This class is a BASIC implementation, and that
 * should be kept in mind
 * 
 * @author Keith Power
 * 
 */
public abstract class BasicTestExecuter implements TestExecuter
{
    private String errorInfo;

    public BasicTestExecuter()
    {
	super();
	// TODO Auto-generated constructor stub
    }

    public boolean test(Test test, Test[] tests)
    {
	// TODO Auto-generated method stub
	if (test.getDependencies().trim().length() > 0)
	{
	    Hashtable allTests = mapTests(tests);

	    String[] dependencies = test.getDependencies().split(",");
	    for (int i = 0; i < dependencies.length; i++)
	    {
		String testKey = dependencies[i].trim();
		if (!allTests.containsKey(testKey))
		{
		    // Dependency not found, fail
		    setErrorInfo(test, "Dependency " + testKey + " not found ");
		    return false;
		}
	    }
	}
	return doTest(test);
    }

    abstract public boolean doTest(Test depTest);

    public String getErrorInfo()
    {
	return this.errorInfo;
    }

    // --------------------- HELPER METHODS
        // --------------------------------------

    protected void setErrorInfo(Test test, String reason)
    {
	this.errorInfo = "Test " + test.getName() + " failed. Reason: "
		+ reason;
	test.setErrorInfo(reason);
    }

    /**
         * Create a Hashtable of tests, using each test's language as its key
         */
    private Hashtable mapTests(Test[] tests)
    {
	Hashtable allTests = new Hashtable();

	for (int i = 0; i < tests.length; i++)
	{
	    if (allTests.put(tests[i].getName(), tests[i]) != null)
	    {
		System.err
			.println("WARNING: Already have a TestExecuter for type "
				+ tests[i].getName());
	    }
	}
	return allTests;
    }

}
